<script>
    // 为什么要在 DynamicAssemblyLoadContext ：AssemblyLoadContext 中重写下Load 方法?

            /*
                        public class DynamicAssemblyLoadContext : AssemblyLoadContext
                        {
                            public DynamicAssemblyLoadContext() : base(isCollectible: true) { } // 可回收

                            这里为什么要重写  Load(AssemblyName assemblyName)这个方法？
                            protected override Assembly? Load(AssemblyName assemblyName)
                            {
                                // 仅加载我们动态生成的程序集
                                return null;
                            }
                        }


                        在 DynamicAssemblyLoadContext 中重写 Load(AssemblyName assemblyName) 方法是为了 "精确控制程序集的加载行为"  ，

                        这对动态编译场景至关重要。  具体原因如下：
            */

                    /*
                            1、理解 AssemblyLoadContext 的加载机制：

                                    AsseemblyLoadContext (ALC) 是 .NET Core 及以上版本中负责加载程序集的核心组件。

                                    当你通过  ALC加载一个程序集时：

                                            1、首先会加载你直接指定的程序集 (例如动态编译生成的程序集)

                                            2、当该程序集依赖其他程序集 (System.dll 或 自定义库)时，CLR 会触发自动Load(AssemblyName assemblyName)方法，
                                                    
                                                    请求ALC加载这些依赖项。

                                    如果不重写这个方法，默认实现会委托给默认的 ALC (通常是应用程序的默认加载上下文) ，这可能导致不符合预期的行为。
                    */

                    /*
                            2、重写的核心目的： 隔离与控制

                                    在动态编译的场景中，重写 Load(AssemblyName assemblyName) 主要是为了：

                                            <1>、避免意外加载无关程序集

                                                    动态生成的程序集可能依赖 系统库 (如 System.Console) 或 其他基础库。
                                                    
                                                    如果直接使用默认实现，ALC可能会从默认上下文加载这些依赖，而我们希望：

                                                        ①、系统级别的基础库 (如  mscorlib、System) 直接使用默认向下文的版本(避免重复加载)

                                                        ②、对于"动态程序集特有的依赖" ,才由当前ALC处理。

                                                    在示例代码中返回 null ，表示 "当前ALC无法处理这个依赖，请让默认ALC来加载"。
                                                    
                                                    这是一种安全的默认策略-----既保证系统库的正常加载，又不额外加载无关程序集。

                                            <2>、实现程序集隔离

                                                    如果你的动态程序集需要加载 "自定义依赖"(而非系统库)，可以在Load方法中添加逻辑，
                                                    
                                                    仅加载指定路径或符合特定条件的程序集。

                                                    eg:

                                                        protected override Assembly? Load(AssemblyName assemblyName)
                                                        {
                                                            // 仅加载我们自己的动态依赖（假设命名空间以 "Dynamic." 开头）
                                                            if (assemblyName.Name?.StartsWith("Dynamic.") == true)
                                                            {
                                                                // 从指定路径加载自定义依赖
                                                                string path = Path.Combine("动态依赖目录", $"{assemblyName.Name}.dll");
                                                                return LoadFromAssemblyPath(path);
                                                            }
                                                            
                                                            // 其他依赖交给默认 ALC 处理
                                                            return null;
                                                        }  

                                                    这种方式可以确保动态程序集的依赖于主程序的依赖完全隔离，避免版本冲突。


                                            <3>、配合可卸载特性

                                                    示例中 DynamicAssemblyLoadContext 被标记为 isCollectible:true(可回收),目的是支持程序集卸载。

                                                    但卸载的前提是：  该ALC加载的所有程序集及其依赖都没有被外部引用。

                                                    通过重写 Load 方法，可以精确控制哪些程序集由当前ALC加载，从而确保：

                                                        ①、 只有"动态生成的程序集"及其"专属依赖"被纳入 "可卸载的范文"

                                                        ②、系统库等公共依赖仍由默认ALC管理，不影响卸载逻辑。
                    */

                    /*
                        3、不重写会怎样？

                                如果删除 Load 方法的重写，会使用 AssemblyLoadContext 的默认实现，其行为是：

                                        ①、尝试从当前ALC的上下文中加载程序集

                                        ②、如果找不到，就委托给默认的应用程序ALC

                                这在大多数情况下不会报错，但可能导致：

                                        ①、动态程序集的依赖被重复加载 (如果默认ALC已经加载过相同的程序集)

                                        ②、无法隔离自定义依赖，增加卸载失败的风险(例如,外部引用了ALC加载的依赖)。

                                        ③、难以控制加载来源 (例如，意外加载了磁盘上的旧版本程序集)
                    */

                    /*
                        总结：

                                重写  Load(AssemblyName assemblyName))是为了 在动态编译场景中实现 "精确控制" 和 "隔离性"：

                                     1、决定哪些依赖由当前ALC加载，哪些交给默认上下文

                                     2、避免意外加载无关程序集，降低内存泄露风险

                                     3、配合 isCollectible :true  确保动态程序集可以被安全卸载

                                这是.NET 中管理动态程序集声明周期的最佳实践之一。
                    */
</script>